package org.xxpay.pay.channel.yunhaofu;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Component;
import org.xxpay.common.http.HttpRequestTemplate;
import org.xxpay.common.util.Util;
import org.xxpay.common.util.sign.SignUtils;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BasePayment;
import org.xxpay.pay.channel.zhifu.ZhifuConfig;

import java.util.*;

@Component
public class YunhaofuPaymentService extends BasePayment {

    private final static String logPrefix = "【云好付】";

    // 下单
    private final static String ORDER_CREATE_STR = "/pay.php";
    // 订单查询
    private final static String ORDER_QUERY_STR = "/api/query";

    @Override
    public String getChannelName() {
        return YunhaofupayConfig.CHANNEL_NAME;
    }

    @Override
    public JSONObject pay(PayOrder payOrder) {
        String channelId = payOrder.getChannelId();
        JSONObject retObj;
        switch (channelId) {
            case YunhaofupayConfig.CHANMEL_NAME_ALI_H5:
                retObj = doOrderReq(payOrder);
                break;
            case YunhaofupayConfig.CHANMEL_NAME_WX_QR:
                retObj = doOrderReq(payOrder);
                break;
            case YunhaofupayConfig.CHANMEL_NAME_ALI_QR:
                retObj = doOrderReq(payOrder);
                break;
            default:
                retObj = buildRetObj(PayConstant.RETURN_VALUE_FAIL, "不支持的渠道[channelId="+channelId+"]");
                break;
        }

        return retObj;
    }

    private JSONObject doOrderReq(PayOrder payOrder) {
        YunhaofupayConfig yunhaofupayConfig = new YunhaofupayConfig(getPayParam(payOrder));
        // 请求参数
        Map<String, String> reqPrameters = Maps.newHashMap();
        reqPrameters.put("version", "1.0");
        reqPrameters.put("merchantNo", yunhaofupayConfig.getMchId());
        reqPrameters.put("orderNo", payOrder.getPayOrderId());
        reqPrameters.put("amount", Util.conversionYuanAmount(payOrder.getAmount()).toString());
        reqPrameters.put("cur", "1");
        reqPrameters.put("productName", "充值");
        reqPrameters.put("notifyUrl", payConfig.getNotifyUrl(getChannelName()));
        reqPrameters.put("frpCode", yunhaofupayConfig.getPayMode());

        String signTxt = getSignToken(reqPrameters);

        _log.info("{}通道签名前字符串{}", logPrefix, signTxt+yunhaofupayConfig.getPrivateKey());

        String sign = SignUtils.MD5.createSign(signTxt, yunhaofupayConfig.getPrivateKey(), SignUtils.CHARSET_UTF8);
        reqPrameters.put("sign", sign);
        _log.info("{}请求数据:{}", getChannelName(), JSON.toJSONString(reqPrameters));

        // 将订单改为支付中
        rpcCommonService.rpcPayOrderService.updateStatus4Ing(payOrder.getPayOrderId(), null);

        JSONObject retObj = new JSONObject();

        HttpRequestTemplate requestTemplate = new HttpRequestTemplate(null);
        JSONObject origin = requestTemplate.postForObject(getReqUrl(yunhaofupayConfig.getRequestUrl(), ORDER_CREATE_STR), reqPrameters, JSONObject.class);
        _log.info("{}下单 单同步请求响应参数：{}", logPrefix, origin.toJSONString());

        if (origin.getString("status").equals(YunhaofupayConfig.RESPONSE_RESULT_OK)){
            // 支付链接地址
            String codeUrl = origin.getString("rc_Result");
            return buildPayResultOfCodeURL(retObj, payOrder, codeUrl);
        }

        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, origin.getString("status"));

        return retObj;
    }
    /**
     * 生成签名
     * @param map
     * @return
     */
    public String getSignToken(Map<String, String> map) {
        String result = "";
        try {
            List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(map.entrySet());
            // 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）
            Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {

                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                    return (o1.getKey()).compareTo(o2.getKey());
                }
            });
            // 构造签名键值对的格式
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String> item : infoIds) {
                if (item.getKey() != null || item.getKey() != "") {
                    String val = item.getValue();
                    if (!(val == "" || val == null)) {
                        sb.append(val);
                    }
                }
            }
            result = sb.toString();
        } catch (Exception e) {
            return null;
        }
        return result;
    }
}
